import React, { Component, PropTypes } from 'react';
import { connect } from 'dva';
import { deepEqual } from '../../utils/objects';
import { Table, Pagination, Dropdown, Button, Menu, Checkbox, Icon, Tooltip } from 'antd';
import filterItemCreate from './FilterItem'
import * as common from '../../utils/common'

class CustomDataTable extends Component {
    constructor(props) {
        super(props);
        let colIds = {}
        this.props.columns.map((c, i) => colIds[i] = c.dispaly ? true : false)
        let { modelName, daoName } = this.props
        modelName = modelName ? modelName : daoName
        this.state = {
            showColumnIds: colIds,
            visibleItemsMenu: false,
            modelName: modelName
        };
    }
    componentWillReceiveProps(nextProps) {
        let colIds = {}
        nextProps.columns.map((c, i) => colIds[i] = c.dispaly ? true : false)
        if (!deepEqual(this.state.showColumnIds, colIds)) {
            this.setState({ showColumnIds: colIds });
        }
    }
    selectChangeHandler(selectedRowKeys) {
        const daoName = this.props.daoName
        if (this.props.onSelectChange) {
            const oldRowKeys = this.props.selectedRowKeys
            let newList = []
            const list = this.props.dataSource
            const key = this.props.keyName
            selectedRowKeys.map(nKey => {
                let find = false
                for (let i = 0; i < oldRowKeys.length; i++) {
                    if (nKey === oldRowKeys[i]) {
                        find = true
                        break
                    }
                }
                if (!find) {
                    const index = list.findIndex(data => data[key] === nKey)
                    if (index !== -1) {
                        newList.push(list[index])
                    }
                }
            })
            let delKeys = []
            oldRowKeys.map(oKey => {
                let find = false
                for (let i = 0; i < selectedRowKeys.length; i++) {
                    if (oKey === selectedRowKeys[i]) {
                        find = true
                        break
                    }
                }
                if (!find) {
                    delKeys.push(oKey)
                }
            })
            this.props.onSelectChange(newList, delKeys)
        }
        const { modelName } = this.state
        this.props.dispatch({
            type: `${modelName}/setSelectedRowKeys`,
            payload: { selectedRowKeys }
        });
    }
    rowClickHandler(d, i, e) {
        if (e.target.tagName === "TD") {
            const list = this.props.dataSource
            const key = this.props.keyName
            let rowKeys = [list[i][key]]
            if (this.props.multiSelect) {
                rowKeys = this.props.selectedRowKeys.concat();
                const index = rowKeys.indexOf(d[key])
                if (index === -1) {
                    rowKeys.push(d[key])
                } else {
                    rowKeys.splice(index, 1)
                }
            }
            this.selectChangeHandler(rowKeys)
        }
    }
    rowClassName(record, index) {
        if (!this.props.multiSelect) {
            const rowKeys = this.props.selectedRowKeys
            if (rowKeys.length > 0) {
                const key = this.props.keyName
                const list = this.props.dataSource
                let rowKey = list[index][key]
                if (rowKey === rowKeys[0]) {
                    return "selected-row"
                }
            }
        }
        return null
    }
    pageChangeHandler(page) {
        const { pageSize, sorter, filters, daoName } = this.props;
        const { modelName } = this.state
        this.props.dispatch({
            type: `${modelName}/fetch`,
            payload: { modelName, daoName, page, pageSize, sorter, filters },
        });
    }
    pageSizeChangeHandler(e) {
        const pageSize = e.key
        const { page, sorter, filters, daoName } = this.props;
        const { modelName } = this.state
        this.props.dispatch({
            type: `${modelName}/fetch`,
            payload: { modelName, daoName, page, pageSize, sorter, filters },
        });
    }
    handleTableChange(_, filters2, sorter) {
        const { page, pageSize, filters, daoName } = this.props;
        const { modelName } = this.state
        this.props.dispatch({
            type: `${modelName}/fetch`,
            payload: { modelName, daoName, page, pageSize, sorter, filters }
        });
    }
    itemChangeHandler(i, e) {
        const checked = e.target.checked
        this.state.showColumnIds[i] = checked;
        this.setState({})
    }
    handleVisibleChange(flag) {
        this.setState({ visibleItemsMenu: flag });
    }
    handleFilterVisibleChange(name, visible) {
        if (!visible) {
            return
        }
        let filterName = null
        if (visible) {
            filterName = name
        }
        const { modelName } = this.state
        this.props.dispatch({
            type: `${modelName}/setVisibleFilterName`,
            payload: { visibleFilterName: filterName }
        });
    }
    getFilterDropdown(name) {
        const { daoName } = this.props;
        let cont = this.getControl(name);
        const FilterItem = filterItemCreate(daoName, name)
        return <FilterItem daoName={daoName} control={cont} />
    }
    getControl(name) {
        const controls = this.props.controls
        const controlProxy = this.props.controlProxy
        let cont = null;
        if (controlProxy && controlProxy[name]) {
            name = controlProxy[name]
        }
        for (let i = 0; i < controls.length; i++) {
            if (controls[i].name === name) {
                cont = controls[i]
                break;
            }
        }
        if (!cont) {
            throw new Error(`在controls列表中不存在${name}！`);
        }
        return cont
    }
    clearFilter() {
        const daoName = this.props.daoName
        this.props.dispatch({
            type: `${daoName}/clearFilter`,
            payload: { daoName }
        });
    }
    exportData() {
        let { columns, filters, seeks, sorter, daoName, userID, permID } = this.props;
        let columnHeaders = []
        const getColumns = (c, j, pch) => {
            if (c.children) {
                if (!this.state.showColumnIds[j]) {
                    return;
                }
                const h = { Caption: c.title, Children: [] }
                pch.push(h)
                c.children.map(ch => {
                    getColumns(ch, j, h.Children)
                })
            } else {
                const name = c.caption ? c.caption : c.dataIndex ? c.dataIndex : c.key
                if (!name) {
                    throw new Error(`列"${c.title}"没有配置caption或dataIndex，请修改！`);
                }
                const header = {
                    Name: name,
                    Caption: c.title,
                    Width: c.width
                }
                pch.push(header)
            }
        }
        columns.map((c, j) => {
            getColumns(c, j, columnHeaders)
        })
        let form = document.createElement('form');//定义一个form表单
        let whereCauses = common.filtersTowhereCauses(filters)
        whereCauses = [...whereCauses, ...seeks]
        const orderItems = common.sorterToOrderItems(sorter)
        form.style = "display:none";
        form.target = "_blank";
        form.method = "post";
        form.action = "/api/ExportXlsx/" + daoName;
        let input1 = document.createElement("input");
        input1.type = "hidden";
        input1.name = "WhereCauses";
        input1.value = JSON.stringify(whereCauses);
        let input2 = document.createElement("input");
        input2.type = "hidden";
        input2.name = "OrderItems";
        input2.value = JSON.stringify(orderItems)
        let input3 = document.createElement("input");
        input3.type = "hidden";
        input3.name = "ColumnHeaders";
        input3.value = JSON.stringify(columnHeaders);
        let input4 = document.createElement("input");
        input4.type = "hidden";
        input4.name = "PermID";
        input4.value = "" + permID;
        let input5 = document.createElement("input");
        input5.type = "hidden";
        input5.name = "UserID";
        input5.value = "" + userID;
        document.body.appendChild(form);//将表单放置在web中
        form.appendChild(input1);
        form.appendChild(input2);
        form.appendChild(input3);
        form.appendChild(input4);
        form.appendChild(input5);
        form.submit();
        document.body.removeChild(form)
    }
    changeColumn(c, filters, visibleFilterName) {
        if (c.filter) {
            c.filterDropdown = this.getFilterDropdown(c.key)
            let visible = false;
            if (c.key === visibleFilterName) {
                visible = true;
            }
            c.filterDropdownVisible = visible;
            c.filteredValue = filters[c.key] ? [1] : [];
            c.onFilterDropdownVisibleChange = this.handleFilterVisibleChange.bind(this, c.key)
        }
        if (c.nowrap) {
            c.render = data => <Tooltip placement="topRight" title={data[c.key]} arrowPointAtCenter>
                <span className="col-sql" style={{ width: c.width - 20, margin: 0 }}>{data[c.key]}</span>
            </Tooltip>
        }
        return c
    }
    render() {
        const { columns, width, height, bordered, dataSource, loading, size, currentPage, pageSize, total, offsetHeight, keyName, selectedRowKeys, visibleFilterName, filters, footer, footerPageDisabled, canPage, canChange, canFilter } = this.props;
        let x = width, y = height
        if (width === 0) {
            columns.map((c) => {
                x = x + (c.width ? c.width : 100)
            })
        }
        if (height === 0) {
            y = offsetHeight - 175 - 42
        }
        let cols = []
        let items = []
        const colIds = this.state.showColumnIds
        let checked = false;
        columns.map((c, i) => {
            checked = this.state.showColumnIds[i]
            items.push(<Menu.Item key={i}><Checkbox checked={checked} onChange={this.itemChangeHandler.bind(this, i)}>{c.title}</Checkbox></Menu.Item>)
            if (colIds[i]) {
                if (c.children) {
                    c.children = c.children.map((cc, i) => {
                        return this.changeColumn(cc, filters, visibleFilterName)
                    })
                } else {
                    c = this.changeColumn(c, filters, visibleFilterName)
                }
                cols.push(c);
            }
        })
        const menu = (<Menu>{items}</Menu>);
        const menu2 = (<Menu onClick={this.pageSizeChangeHandler.bind(this)}>
            <Menu.Item key="10">每页显示10行</Menu.Item>
            <Menu.Item key="20">每页显示20行</Menu.Item>
            <Menu.Item key="30">每页显示30行</Menu.Item>
            <Menu.Item key="40">每页显示40行</Menu.Item>
            <Menu.Item key="50">每页显示50行</Menu.Item>
            <Menu.Item key="200">每页显示200行</Menu.Item>
            <Menu.Item key="1000">每页显示1000行</Menu.Item>
        </Menu>);
        let exportButton = ""
        if (this.props.canExport) {
            exportButton = <Button style={{ margin: 5 }} key="b_exportData" onClick={this.exportData.bind(this)}>导出excel</Button>
        }
        let rowSelection = null
        if (this.props.multiSelect) {
            rowSelection = { selectedRowKeys, onChange: this.selectChangeHandler.bind(this) }
        }
        const footerStyles = {
            display: footer ? 'block' : 'none'
        }
        return (
            <div>
                <Table
                    title={() => {
                        return <div style={{ textAlign: "center", fontWeight: "bold" }}>绩效资源自定义数据查询</div>
                    }}
                    columns={cols}
                    dataSource={dataSource}
                    loading={loading}
                    onRowClick={this.rowClickHandler.bind(this)}
                    rowKey={record => record[keyName]}
                    scroll={{ x, y }}
                    bordered={bordered}
                    rowSelection={rowSelection}
                    pagination={false}
                    size={size}
                    onChange={this.handleTableChange.bind(this)}
                    rowClassName={this.rowClassName.bind(this)}
                />
                <div style={footerStyles}>
                    {/* {canChange ? <Dropdown overlay={menu2} trigger={['click']} disabled={footerPageDisabled}>
                        <Button type="ghost" style={{ margin: 5 }}>
                            每页显示{pageSize}行 <Icon type="down" />
                        </Button>
                    </Dropdown> : null} */}
                    {/* {canChange ? <Dropdown overlay={menu} trigger={['click']} onVisibleChange={this.handleVisibleChange.bind(this)} visible={this.state.visibleItemsMenu}>
                        <Button type="ghost" style={{ margin: 5 }}>
                            显示项目 <Icon type="down" />
                        </Button>
                    </Dropdown> : null} */}
                    {/* {exportButton} */}
                    {/* {canFilter ? <Button style={{ margin: 5 }} key="b_clearFilter" onClick={this.clearFilter.bind(this)}>清除过滤条件</Button> : null} */}
                    {canPage ? <Pagination style={{ margin: '5px 5px' }}
                        className="ant-table-pagination"
                        total={total}
                        current={currentPage}
                        pageSize={pageSize}
                        showTotal={total => `共${total}条`}
                        onChange={this.pageChangeHandler.bind(this)}
                    /> : null}
                </div>
            </div>
        );
    }
}
CustomDataTable.propTypes = {
    modelName: PropTypes.string,
    daoName: PropTypes.string,
    columns: PropTypes.array,
    controls: PropTypes.array,
    width: PropTypes.number,
    height: PropTypes.number,
    bordered: PropTypes.bool,
    size: PropTypes.string,
    canChange: PropTypes.bool,
    canExport: PropTypes.bool,
    canPage: PropTypes.bool,
    multiSelect: PropTypes.bool,
    permID: PropTypes.number,
    controlProxy: PropTypes.object,
    onSelectChange: PropTypes.func,
    footer: PropTypes.bool,//是否隐藏页脚
    footerPageDisabled: PropTypes.bool,//禁用选择页数
    loading: PropTypes.bool,
};
CustomDataTable.defaultProps = {
    columns: [],
    controls: [],
    width: 0,
    height: 0,
    bordered: true,
    size: "middle",
    canChange: true,
    canExport: true,
    canPage: true,
    canFilter: true,
    multiSelect: false,
    footer: true,
    footerPageDisabled: false,
};

export default function dataTableCreate(modelName) {
    function mapStateToProps(state, props) {
        const { list, total, page, pageSize, sorter, filters, seeks, selectedRowKeys, keyName, visibleFilterName } = state[modelName];
        const { offsetHeight, offsetWidth, collapsedLeftMenu, userID } = state.menus
        return {
            loading: state.loading.models[modelName],
            dataSource: list,
            total,
            currentPage: page,
            pageSize,
            sorter,
            filters,
            seeks,
            offsetHeight,
            offsetWidth,
            collapsedLeftMenu,
            selectedRowKeys,
            keyName,
            visibleFilterName,
            userID
        }
    }
    return connect(mapStateToProps)(CustomDataTable);
}
